home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / lfs / lfsStableMem.c < prev    next >
C/C++ Source or Header  |  1991-08-08  |  18KB  |  605 lines

  1. /* 
  2.  * LfsStableMem.c --
  3.  *
  4.  *    Generic routines for supporting an in memory data structure that
  5.  *    is written to a LFS log at each checkpoint.  The blocks of the
  6.  *    data structures are kept as file in the file cache.
  7.  *
  8.  * Copyright 1989 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/lfs/RCS/lfsStableMem.c,v 1.8 91/08/08 17:51:18 mendel Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include <lfsInt.h>
  23. #include <lfsSeg.h>
  24. #include <lfsStableMemInt.h>
  25. #include <stdlib.h>
  26. #include <fsdm.h>
  27.  
  28. static Boolean AddBlockToSegment _ARGS_((LfsStableMem *smemPtr, 
  29.             Address address, int blockNum, ClientData clientData,
  30.             LfsSeg *segPtr));
  31. static Boolean BlockMatch _ARGS_((Fscache_Block *blockPtr, 
  32.             ClientData clientData));
  33.  
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * LfsStableMemLoad --
  40.  *
  41.  *     Allocate and load a LFS stable memory resident data structure.
  42.  *
  43.  * Results:
  44.  *    SUCCESS if load succeed ok.
  45.  *
  46.  * Side effects:
  47.  *    Many
  48.  *
  49.  *----------------------------------------------------------------------
  50.  */
  51.  
  52. ReturnStatus
  53. LfsStableMemLoad(lfsPtr, smemParamsPtr, checkPointSize, checkPointPtr, smemPtr)
  54.     Lfs *lfsPtr;       /* File system of metadata. */
  55.     LfsStableMemParams  *smemParamsPtr; /* Parameters for this memory. */
  56.     int  checkPointSize;   /* Size of checkpoint data. */
  57.     char *checkPointPtr;   /* Data from last checkpoint before shutdown. */
  58.     LfsStableMem    *smemPtr; /* In memeory index data structures. */
  59. {
  60.     int    blockNum, bufferSize; 
  61.     LfsStableMemCheckPoint *cpPtr;
  62.     Fscache_Attributes       attr;
  63.     static    int    nextMinorNumber = -1;
  64.  
  65.     cpPtr = (LfsStableMemCheckPoint *)     checkPointPtr;
  66.     /*
  67.      * Do some bounds checking on the checkpoint buffer.
  68.      */
  69.     if ((checkPointSize < sizeof(LfsStableMemCheckPoint)) ||
  70.         (checkPointSize < (cpPtr->numBlocks * sizeof(int) + 
  71.                 sizeof(LfsStableMemCheckPoint))))  {
  72.     return FAILURE;
  73.     }
  74.     /*
  75.      * Fill in the LfsStableMem data structures.
  76.      *
  77.      */
  78.     smemPtr->lfsPtr = lfsPtr;
  79.     /*
  80.      * Initialize the file handle used for storing blocks in the
  81.      * file cache.
  82.      */
  83.  
  84.     bzero((Address)&smemPtr->dataHandle, sizeof(smemPtr->dataHandle));
  85.     smemPtr->dataHandle.hdr.fileID.serverID = rpc_SpriteID;
  86.     smemPtr->dataHandle.hdr.fileID.major = lfsPtr->domainPtr->domainNumber;
  87.     smemPtr->dataHandle.hdr.fileID.minor = nextMinorNumber--;
  88.     smemPtr->dataHandle.hdr.fileID.type = FSIO_LCL_FILE_STREAM;
  89.     smemPtr->dataHandle.hdr.name = "LfsStableMemFile";
  90.     smemPtr->dataHandle.descPtr = (Fsdm_FileDescriptor *)NIL;
  91.  
  92.     bzero((Address)&attr, sizeof(attr));
  93.     attr.lastByte = smemParamsPtr->blockSize * smemParamsPtr->maxNumBlocks;
  94.     Fscache_FileInfoInit(&smemPtr->dataHandle.cacheInfo,
  95.             (Fs_HandleHeader *) &smemPtr->dataHandle,
  96.             0, TRUE, &attr, lfsPtr->domainPtr->backendPtr);
  97.  
  98.     /*
  99.      * Allocate and copy the index for the metadata.
  100.      */
  101.     bufferSize = smemParamsPtr->maxNumBlocks * sizeof(int);
  102.     smemPtr->blockIndexPtr = (LfsDiskAddr *) malloc(bufferSize);
  103.     bcopy(checkPointPtr + sizeof(LfsStableMemCheckPoint), 
  104.          (char *) smemPtr->blockIndexPtr, 
  105.          cpPtr->numBlocks * sizeof(LfsDiskAddr));
  106.     for (blockNum = cpPtr->numBlocks; blockNum < smemParamsPtr->maxNumBlocks;
  107.             blockNum++) {
  108.     LfsSetNilDiskAddr(&smemPtr->blockIndexPtr[blockNum]);
  109.     }
  110.  
  111.     smemPtr->numCacheBlocksOut = 0;
  112.     /*
  113.      * Fillin the rest of the LfsStableMem data structure with a copy
  114.      * of the checkPoint and Params data.
  115.      */
  116.  
  117.     smemPtr->checkPoint = *cpPtr;
  118.     smemPtr->params = *smemParamsPtr;
  119.  
  120.     return SUCCESS;
  121. }
  122.  
  123.  
  124. /*
  125.  *----------------------------------------------------------------------
  126.  *
  127.  * LfsStableMemLoad --
  128.  *
  129.  *     Allocate and load a LFS stable memory resident data structure.
  130.  *
  131.  * Results:
  132.  *    SUCCESS if load succeed ok.
  133.  *
  134.  * Side effects:
  135.  *    Many
  136.  *
  137.  *----------------------------------------------------------------------
  138.  */
  139.  
  140. ReturnStatus
  141. LfsStableMemDestory(lfsPtr, smemPtr)
  142.     Lfs *lfsPtr;       /* File system of metadata. */
  143.     LfsStableMem    *smemPtr; /* In memeory index data structures. */
  144. {
  145.     Fscache_FileInvalidate(&smemPtr->dataHandle.cacheInfo, 0, 
  146.             FSCACHE_LAST_BLOCK);
  147.  
  148.     free((char *) smemPtr->blockIndexPtr);
  149.  
  150.     return SUCCESS;
  151. }
  152.  
  153.  
  154. /*
  155.  *----------------------------------------------------------------------
  156.  *
  157.  * LfsStableMemClean --
  158.  *
  159.  *    Routine to handle cleaning pieces containing data for this module.
  160.  *
  161.  * Results:
  162.  *    TRUE if more data needs to be written, FALSE if this module is
  163.  *    happy for the time being.
  164.  *
  165.  * Side effects:
  166.  *    Many
  167.  *
  168.  *----------------------------------------------------------------------
  169.  */
  170.  
  171. Boolean
  172. LfsStableMemClean(segPtr, sizePtr, numCacheBlocksPtr, clientDataPtr, smemPtr)
  173.     LfsSeg *segPtr;    /* Segment containing data to clean. */
  174.     int *sizePtr;
  175.     int *numCacheBlocksPtr;
  176.     ClientData *clientDataPtr;
  177.     LfsStableMem *smemPtr;    /* Index pointer. */
  178. {
  179.     char *summaryPtr;
  180.     int     *blockPtr;
  181.     int     numBlocks, block, blockOffset;
  182.     LfsDiskAddr blockAddress;
  183.     ReturnStatus    status;
  184.     LfsStableMemEntry entry;
  185.  
  186.     summaryPtr = LfsSegGetSummaryPtr(segPtr);
  187.     numBlocks = LfsSegSummaryBytesLeft(segPtr) / sizeof(int);
  188.     blockPtr = (int *) summaryPtr;
  189.     blockAddress = LfsSegDiskAddress(segPtr, LfsSegGetBufferPtr(segPtr));
  190.     blockOffset = 0;
  191.     /*
  192.      * For each block that hasn't moved already, fetch and release the
  193.      * block marking it as dirty.
  194.      */
  195.     for (block = 0; block < numBlocks; block++) { 
  196.     LfsDiskAddr newDiskAddr;
  197.      blockOffset += LfsBytesToBlocks(segPtr->lfsPtr, 
  198.                     smemPtr->params.blockSize);
  199.     LfsDiskAddrPlusOffset(blockAddress, -blockOffset, &newDiskAddr);
  200.     if (LfsSameDiskAddr(smemPtr->blockIndexPtr[blockPtr[block]], 
  201.             newDiskAddr)) {
  202.         int entryNumber = blockPtr[block] * smemPtr->params.entriesPerBlock;
  203.         status = LfsStableMemFetch(smemPtr, entryNumber, 0, &entry);
  204.         if (status != SUCCESS) {
  205.         LfsError(segPtr->lfsPtr, status,"Can't clean metadata block\n");
  206.         }
  207.         LfsStableMemRelease(smemPtr, &entry, TRUE);
  208.         (*sizePtr) += smemPtr->params.blockSize;
  209.      }
  210.     }
  211.     return FALSE;
  212. }
  213.  
  214.  
  215. /*
  216.  *----------------------------------------------------------------------
  217.  *
  218.  * LfsStableMemCheckpoint --
  219.  *
  220.  *    Routine to handle checkpointing of data for this module.
  221.  *
  222.  * Results:
  223.  *    TRUE if more data needs to be written, FALSE if this module is
  224.  *    checkpointed.
  225.  *
  226.  * Side effects:
  227.  *    Many
  228.  *
  229.  *----------------------------------------------------------------------
  230.  */
  231.  
  232. Boolean
  233. LfsStableMemCheckpoint(segPtr, checkPointPtr, flags, checkPointSizePtr,
  234.             clientDataPtr, smemPtr)
  235.     LfsSeg *segPtr;        /* Segment containing data for checkpoint. */
  236.     char   *checkPointPtr;      /* Buffer to write checkpoint data. */
  237.     int       flags;        /* Flags. */
  238.     int       *checkPointSizePtr;  /* Bytes added to the checkpoint area.*/
  239.     ClientData *clientDataPtr;
  240.     LfsStableMem *smemPtr;    /* Stable memory description. */
  241. {
  242.     Boolean    full = FALSE;
  243.  
  244.     full = LfsStableMemLayout(segPtr, LFS_CHECKPOINT_LAYOUT,
  245.             clientDataPtr, smemPtr);
  246.     /*
  247.      * If we didn't fill the segment, copy the index to the checkpoint buffer.
  248.      */
  249.     if (!full) {
  250.     *(LfsStableMemCheckPoint *) checkPointPtr = smemPtr->checkPoint;
  251.     bcopy((char *) smemPtr->blockIndexPtr, 
  252.         checkPointPtr + sizeof(LfsStableMemCheckPoint), 
  253.         sizeof(LfsDiskAddr) * smemPtr->checkPoint.numBlocks);
  254.     *checkPointSizePtr = sizeof(int) * smemPtr->checkPoint.numBlocks + 
  255.                 sizeof(LfsStableMemCheckPoint);
  256.  
  257.     }
  258.     return full;
  259. }
  260.  
  261.  
  262. /*
  263.  *----------------------------------------------------------------------
  264.  *
  265.  * LfsStableMemLayout --
  266.  *
  267.  *    Routine to handle writing of data for this module.
  268.  *
  269.  * Results:
  270.  *    TRUE if more data needs to be written, FALSE if this module is
  271.  *    checkpointed.
  272.  *
  273.  * Side effects:
  274.  *    Many
  275.  *
  276.  *----------------------------------------------------------------------
  277.  */
  278.  
  279. Boolean
  280. LfsStableMemLayout(segPtr, flags, clientDataPtr, smemPtr)
  281.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  282.     int        flags;        /* Layout flags. */
  283.     ClientData    *clientDataPtr;
  284.     LfsStableMem *smemPtr;    /* Stable memory description. */
  285. {
  286.     Boolean    full = FALSE;
  287.     Fscache_FileInfo    *cacheInfoPtr;
  288.     Fscache_Block    *blockPtr;
  289.     int            lastDirtyBlock;
  290.     Boolean        fsyncOnly;
  291.  
  292.  
  293.     /*
  294.      * Find and layout all the dirty metadata blocks. 
  295.      */
  296.     if (*clientDataPtr == (ClientData) NIL) { 
  297.     fsyncOnly = ((flags  & LFS_CHECKPOINT_LAYOUT) == 0);
  298.     cacheInfoPtr = Fscache_GetDirtyFile(
  299.                 segPtr->lfsPtr->domainPtr->backendPtr,
  300.                 fsyncOnly, LfsFileMatch, 
  301.             (ClientData) (smemPtr->dataHandle.hdr.fileID.minor));
  302.     if (cacheInfoPtr == (Fscache_FileInfo *) NIL) {
  303.         return FALSE;
  304.     }
  305.     *clientDataPtr = (ClientData) cacheInfoPtr;
  306.     } else {
  307.     cacheInfoPtr = (Fscache_FileInfo *) *clientDataPtr;
  308.     }
  309.  
  310.     while(!full) { 
  311.     blockPtr = Fscache_GetDirtyBlock(cacheInfoPtr, BlockMatch,
  312.                 (ClientData) 0, &lastDirtyBlock);
  313.     if (blockPtr == (Fscache_Block *) NIL) {
  314.         break;
  315.     }
  316.     full = AddBlockToSegment(smemPtr, blockPtr->blockAddr, 
  317.             blockPtr->blockNum, (ClientData) blockPtr, segPtr);
  318.     if (full) {
  319.         Fscache_ReturnDirtyBlock(blockPtr, GEN_EINTR);
  320.     } else {
  321. #ifdef SOSP91
  322.     Fscache_AddBlockToStats(cacheInfoPtr, blockPtr);
  323. #endif SOSP91
  324.         smemPtr->numCacheBlocksOut++;
  325.     }
  326.  
  327.     }
  328. #ifdef SOSP91
  329.     cacheInfoPtr->flags &= ~FSCACHE_REASON_FLAGS;
  330. #endif SOSP91
  331.     if (!full && (smemPtr->numCacheBlocksOut == 0)) {
  332.     Fscache_ReturnDirtyFile(cacheInfoPtr, FALSE);
  333.     }
  334.     return full;
  335. }
  336.  
  337.  
  338. /*
  339.  *----------------------------------------------------------------------
  340.  *
  341.  * LfsStableMemWriteDone --
  342.  *
  343.  *    Routine to inform this module that a write has finished.
  344.  *
  345.  * Results:
  346.  *    None.
  347.  *
  348.  * Side effects:
  349.  *    Many
  350.  *
  351.  *----------------------------------------------------------------------
  352.  */
  353.  
  354. void
  355. LfsStableMemWriteDone(segPtr, flags, clientDataPtr, smemPtr)
  356.     LfsSeg *segPtr;    /* Segment whose write finishes. */
  357.     int        flags;    /* Write done flags. */
  358.     ClientData *clientDataPtr;
  359.     LfsStableMem *smemPtr;    /* Index description. */
  360. {
  361.     LfsSegElement *bufferLimitPtr, *bufferPtr = LfsSegGetBufferPtr(segPtr);
  362.     Fscache_Block *blockPtr;
  363.  
  364.     blockPtr = (Fscache_Block *) NIL;
  365.     bufferLimitPtr = bufferPtr + LfsSegSummaryBytesLeft(segPtr) / sizeof(int);
  366.     while (bufferPtr < bufferLimitPtr) {
  367.     blockPtr = (Fscache_Block *) bufferPtr->clientData;
  368.     Fscache_ReturnDirtyBlock(blockPtr, SUCCESS);
  369.     bufferPtr++;
  370.     smemPtr->numCacheBlocksOut--;
  371.     }
  372.     if (smemPtr->numCacheBlocksOut == 0) {
  373.     Fscache_ReturnDirtyFile((Fscache_FileInfo *)(*clientDataPtr), FALSE);
  374.     }
  375.     LfsSegSetBufferPtr(segPtr, bufferPtr);
  376. }
  377. /*
  378.  *----------------------------------------------------------------------
  379.  *
  380.  * LfsStableMemFetch --
  381.  *
  382.  *    Routine to fetch a stable memory entry and optionally release
  383.  *    a previously fetched entry.   This routine fetches the data block
  384.  *    from the file cache reading it in if it is not present.
  385.  *
  386.  * Results:
  387.  *    SUCCESS if entry is fetch. GEN_INVALID_ARG if entryNumber is not
  388.  *    vaild. Other ReturnStatus if disk read fails.
  389.  *
  390.  * Side effects:
  391.  *    Cache block fetched. Possibly disk I/O performed.
  392.  *
  393.  *----------------------------------------------------------------------
  394.  */
  395.  
  396. ReturnStatus
  397. LfsStableMemFetch(smemPtr, entryNumber, flags, entryPtr)
  398.     LfsStableMem *smemPtr;    /* Index description. */
  399.     int         entryNumber;    /* Entry number wanted. */
  400.     int        flags;    /* LFS_STABLE_MEM_MAY_DIRTY | LFS_STABLE_MEM_REL_ENTRY*/
  401.     LfsStableMemEntry *entryPtr; /* IN/OUT: Stable memory entry returned. */
  402. {
  403.     Fscache_Block        *blockPtr;
  404.     Boolean            found;
  405.     int         blockNum, offset;
  406.     ReturnStatus    status = SUCCESS;
  407.     Boolean        releaseEntry;
  408.     LfsStableMemBlockHdr *hdrPtr;
  409.  
  410.     releaseEntry = ((flags & LFS_STABLE_MEM_REL_ENTRY) != 0);
  411.     if ((entryNumber < 0) || (entryNumber >= smemPtr->params.maxNumEntries)) {
  412.     if (releaseEntry) {
  413.         LfsStableMemRelease(smemPtr, entryPtr, entryPtr->modified);
  414.     }
  415.     return GEN_INVALID_ARG;
  416.     }
  417.     blockNum = entryNumber / smemPtr->params.entriesPerBlock;
  418.     offset = (entryNumber % smemPtr->params.entriesPerBlock) * 
  419.         smemPtr->params.entrySize + sizeof(LfsStableMemBlockHdr);
  420.     blockPtr = (Fscache_Block *) NIL;
  421.     if (releaseEntry) {
  422.     if (entryPtr->blockNum == blockNum) { 
  423.         blockPtr = (Fscache_Block *) entryPtr->clientData;
  424.     } else {
  425.         LfsStableMemRelease(smemPtr, entryPtr, entryPtr->modified);
  426.     }
  427.     }
  428.     if (blockPtr == (Fscache_Block *) NIL) {
  429.     Boolean dirtied;
  430.     int    cacheFlags;
  431.     /*
  432.      * Fetch the block from the cache reading it in if needed.
  433.      */
  434.     cacheFlags = FSCACHE_DESC_BLOCK|FSCACHE_CANT_BLOCK;
  435.     if (flags & LFS_STABLE_MEM_MAY_DIRTY) {
  436.         cacheFlags |= FSCACHE_IO_IN_PROGRESS;
  437.     }
  438.     Fscache_FetchBlock(&smemPtr->dataHandle.cacheInfo, blockNum, 
  439.                  cacheFlags, &blockPtr, &found);
  440.     dirtied = FALSE;
  441.     if (!found && (blockPtr != (Fscache_Block *) NIL) ) {
  442.         if (LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  443.         bzero(blockPtr->blockAddr, smemPtr->params.blockSize);
  444.         hdrPtr = (LfsStableMemBlockHdr *) blockPtr->blockAddr;
  445.         hdrPtr->magic = LFS_STABLE_MEM_BLOCK_MAGIC;
  446.         hdrPtr->memType = smemPtr->params.memType;
  447.         hdrPtr->blockNum = blockNum;
  448.         dirtied = TRUE;
  449.          } else {
  450.         status = LfsReadBytes(smemPtr->lfsPtr, 
  451.                      smemPtr->blockIndexPtr[blockNum],
  452.                      smemPtr->params.blockSize, 
  453.                      blockPtr->blockAddr);
  454. #ifdef ERROR_CHECK
  455.          if (smemPtr->params.memType != LFS_SEG_USAGE_MOD) {
  456.              LfsCheckRead(smemPtr->lfsPtr, 
  457.                 smemPtr->blockIndexPtr[blockNum], 
  458.                 smemPtr->params.blockSize);
  459.           }
  460. #endif
  461.          }
  462.  
  463.          if (status != SUCCESS) {
  464.         Fscache_UnlockBlock(blockPtr, 0, -1, 0, FSCACHE_DELETE_BLOCK);
  465.          }
  466.     }
  467.     entryPtr->modified = dirtied;
  468.     }
  469.     if (blockPtr != (Fscache_Block *) NIL) {
  470. #ifdef ERROR_CHECK
  471.     hdrPtr = (LfsStableMemBlockHdr *) blockPtr->blockAddr;
  472.     if ((hdrPtr->magic != LFS_STABLE_MEM_BLOCK_MAGIC) || 
  473.         (hdrPtr->memType != smemPtr->params.memType) ||
  474.         (hdrPtr->blockNum != blockNum)) {
  475.         LfsError(smemPtr->lfsPtr, FAILURE, "Bad LfsStableMemBlockHdr\n");
  476.     }
  477. #endif /* ERROR_CHECK */
  478.     entryPtr->addr = blockPtr->blockAddr + offset;
  479.     entryPtr->blockNum = blockNum;
  480.     entryPtr->clientData = (ClientData) blockPtr;
  481.     } else {
  482.     status = FS_WOULD_BLOCK;
  483.     }
  484.     return status;
  485. }
  486.  
  487. /*
  488.  *----------------------------------------------------------------------
  489.  *
  490.  * LfsStableMemRelease --
  491.  *
  492.  *    Routine to release a previous fetched stable memory ebtrt,
  493.  *
  494.  * Results:
  495.  *    None.
  496.  *
  497.  * Side effects:
  498.  *    Many
  499.  *
  500.  *----------------------------------------------------------------------
  501.  */
  502.  
  503. void
  504. LfsStableMemRelease(smemPtr, entryPtr, modified)
  505.     LfsStableMem *smemPtr;    /* Index description. */
  506.     LfsStableMemEntry *entryPtr; /*  Stable memory entry to return. */
  507.     Boolean    modified;    /* TRUE if block was modified. */
  508. {
  509.     Fscache_Block        *blockPtr;
  510.     int            timeDirtied, blockNum;
  511.  
  512.     blockPtr = (Fscache_Block *) entryPtr->clientData;
  513.     blockNum = blockPtr->blockNum;
  514.     modified = modified || entryPtr->modified;
  515.     timeDirtied = modified ? -1 : 0;
  516.     Fscache_UnlockBlock(blockPtr, timeDirtied, blockNum,  
  517.             smemPtr->params.blockSize, 0);
  518.     entryPtr->addr = (Address)NIL;
  519.     if (modified && !LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  520.         /*
  521.      * If the block was modified free the old address up.
  522.      */
  523.     LfsSegUsageFreeBlocks(smemPtr->lfsPtr, 
  524.         (int)(smemPtr->params.blockSize), 1, 
  525.         (LfsDiskAddr *) smemPtr->blockIndexPtr + blockNum);
  526.  
  527.     }
  528.     return;
  529. }
  530.  
  531. /*
  532.  *----------------------------------------------------------------------
  533.  *
  534.  * AddBlockToSegment --
  535.  *
  536.  *    Add a metadata block to the specified segment.
  537.  *
  538.  * Results:
  539.  *    TRUE if segment is full so we couldn't add block.
  540.  *
  541.  * Side effects:
  542.  *    None.
  543.  *
  544.  *----------------------------------------------------------------------
  545.  */
  546.  
  547.  
  548. static Boolean
  549. AddBlockToSegment(smemPtr, address, blockNum, clientData, segPtr)
  550.     LfsStableMem *smemPtr;    /* Index of block. */
  551.     Address      address;    /* Address of block. */
  552.     int        blockNum;    /* Block number. */
  553.     ClientData    clientData;    /* Client data for entry. */
  554.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  555. {
  556.     int    fsBlocks;
  557.     char *summaryPtr;
  558.     LfsSegElement *bufferPtr;
  559.  
  560.     fsBlocks = LfsBytesToBlocks(segPtr->lfsPtr, smemPtr->params.blockSize);
  561.     summaryPtr = LfsSegGrowSummary(segPtr, fsBlocks, sizeof(int));
  562.     if (summaryPtr == (char *)NIL) {
  563.     return TRUE;
  564.     }
  565.     bufferPtr = LfsSegAddDataBuffer(segPtr, fsBlocks, address, clientData);
  566.     *(int *)summaryPtr = blockNum;
  567.     LfsSegSetSummaryPtr(segPtr,summaryPtr + sizeof(int));
  568. #ifdef ERROR_CHECK
  569.     if (!LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  570.     panic("StableMem:AddBlockToSegment disk address not NIL\n");
  571.     }
  572. #endif
  573.     smemPtr->blockIndexPtr[blockNum] = LfsSegDiskAddress(segPtr, bufferPtr);
  574.     segPtr->activeBytes += smemPtr->params.blockSize;
  575.     if (blockNum >= smemPtr->checkPoint.numBlocks) {
  576.     smemPtr->checkPoint.numBlocks = blockNum + 1;
  577.     }
  578.     return FALSE;
  579. }
  580.  
  581.  
  582. /*
  583.  * ----------------------------------------------------------------------------
  584.  *
  585.  * BlockMatch --
  586.  *
  587.  *     Cache backend block type match.  
  588.  *
  589.  * Results:
  590.  *    TRUE.
  591.  *
  592.  * Side effects:
  593.  *
  594.  * ----------------------------------------------------------------------------
  595.  */
  596. /*ARGSUSED*/
  597. static Boolean
  598. BlockMatch(blockPtr, clientData)
  599.     Fscache_Block *blockPtr;
  600.     ClientData       clientData;
  601. {
  602.     return TRUE;
  603. }
  604.  
  605.